package com.efounder.frame.listener;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;

import com.efounder.mobilemanager.R;

/**
 * Created by XinQing on 2016/12/30.
 * 上下左右滑动监听
 */

public class EFOnTouchUDLRFlingListener implements View.OnTouchListener{
    public static final int FLING_NO = -1;
    public static final int FLING_UP = 0;
    public static final int FLING_DOWN = 1;
    public static final int FLING_LEFT = 2;
    public static final int FLING_RIGHT = 3;

    private Context context;

    private OnFlingUpListener onFlingUpListener;
    private OnFlingDownListener onFlingDownListener;
    private OnFlingLeftListener onFlingLeftListener;
    private OnFlingRightListener onFlingRightListener;
    private OnTouchDelegate onTouchDelegate;

    //手指滑动时的最小速度(单位dp)
    private int upMinFlingSpeed = 50;
    private int downMinFlingSpeed = 50;
    private int leftMinFlingSpeed = 50;
    private int rightMinFlingSpeed = 50;

    protected float downX = -1;
    protected float downY = -1;
    protected int xTriggerRange = 60;//X轴触发范围
    protected int yTriggerRange = 60;//Y轴触发范围
    //用于计算手指滑动的速度。
    protected VelocityTracker mVelocityTracker;
    //是否消费掉touch事件
    protected boolean isConsumeTouchEvent = true;

    private int mTouchSlop;

    public EFOnTouchUDLRFlingListener(Context context) {
        this.context = context;
        xTriggerRange = convertToDP(xTriggerRange);
        yTriggerRange = convertToDP(yTriggerRange);
        upMinFlingSpeed = convertToDP(upMinFlingSpeed);
        downMinFlingSpeed = convertToDP(downMinFlingSpeed);
        leftMinFlingSpeed = convertToDP(leftMinFlingSpeed);
        rightMinFlingSpeed = convertToDP(rightMinFlingSpeed);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    private int convertToDP(int dp){
        return (int) (dp * context.getResources().getDisplayMetrics().density);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.i("EFActivity","EFOnTouchUDLRFlingListener-----onTouch");
        if (onTouchDelegate != null){
            onTouchDelegate.onTouch(v,event);
        }
        createVelocityTracker(event);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                Log.i("EFActivity","EFOnTouchUDLRFlingListener-----ACTION_DOWN");
                downX = event.getRawX();
                downY = event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("EFActivity","EFOnTouchUDLRFlingListener-----ACTION_MOVE");
                if (downX == -1) downX = event.getRawX();
                if (downY == -1) downY = event.getRawY();
                if (Math.abs(event.getRawX() - downX) > xTriggerRange){//如果有左右滑动意向
                    Log.i("EFActivity","EFOnTouchUDLRFlingListener-----onTouch---有左右滑动意向");
//                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                Log.i("EFActivity","EFOnTouchUDLRFlingListener-----ACTION_UP");
                v.performClick();
                //获取速度
                int xSpeed = getFlingXVelocity();
                int ySpeed = getFlingYVelocity();
                int flingOrientation = getFlingOrientation(event.getRawX(),event.getRawY(),xSpeed,ySpeed);
                switch (flingOrientation){
                    case FLING_UP:
                        Log.i("-----","EFOnTouchUDLRFlingListener-----FLING_UP");
                        if (onFlingUpListener != null){
                            onFlingUpListener.onFlingUp(v,event);
                        }
                        break;
                    case FLING_DOWN:
                        Log.i("-----","EFOnTouchUDLRFlingListener-----FLING_DOWN");
                        if (onFlingDownListener != null){
                            onFlingDownListener.onFlingDown(v,event);
                        }
                        break;
                    case FLING_LEFT:
                        Log.i("-----","EFOnTouchUDLRFlingListener-----FLING_LEFT");
                        if (onFlingLeftListener != null){
                            onFlingLeftListener.onFlingLeft(v,event);
                        }
                        break;
                    case FLING_RIGHT:
                        Log.i("-----","EFOnTouchUDLRFlingListener-----FLING_RIGHT");
                        if (onFlingRightListener != null){
                            onFlingRightListener.onFlingRight(v,event);
                        }
                        break;
                    case FLING_NO:
                        Log.i("-----","EFOnTouchUDLRFlingListener-----FLING_NO");
                        break;
                }
                recycleVelocityTracker();
                downX = -1;
                downY = -1;
                break;
            case MotionEvent.ACTION_CANCEL:
                downX = -1;
                downY = -1;
                break;
            default:
                downX = -1;
                downY = -1;
                break;
        }
        return isConsumeTouchEvent;
    }


    protected int getFlingOrientation(float upX,float upY,int xSpeed,int ySpeed){
        //1.判断滑动方向(上下还是左右)
        if (Math.abs(upX - downX) > Math.abs(upY - downY) ){//左右
            if (upX < downX){//左
                //2.左右范围 > xTriggerRange，上下范围 < yTriggerRange,xSpeed > leftMinFlingSpeed
                if (Math.abs(upX - downX) > xTriggerRange && Math.abs(upY - downY) < yTriggerRange && xSpeed > leftMinFlingSpeed){
                    return FLING_LEFT;
                }
            }else {//右
                //2.左右范围 > xTriggerRange，上下范围 < yTriggerRange,xSpeed > rightMinFlingSpeed
                if (Math.abs(upX - downX) > xTriggerRange && Math.abs(upY - downY) < yTriggerRange && xSpeed > rightMinFlingSpeed){
                    return FLING_RIGHT;
                }
            }
        }else {//上下
            if (upY < downY){//上
                //2.上下范围 > yTriggerRange,左右范围 < xTriggerRange，ySpeed > upMinFlingSpeed
                if (Math.abs(upY - downY) > yTriggerRange && Math.abs(upX - downX) < xTriggerRange &&  ySpeed > upMinFlingSpeed){
                    return FLING_UP;
                }
            }else{//下
                //2.上下范围 > yTriggerRange,左右范围 < xTriggerRange，ySpeed > downMinFlingSpeed
                if (Math.abs(upY - downY) > yTriggerRange && Math.abs(upX - downX) < xTriggerRange &&  ySpeed > downMinFlingSpeed){
                    return FLING_DOWN;
                }
            }
        }

        return FLING_NO;
    }

    /**
     * 创建VelocityTracker对象，并将触摸content界面的滑动事件加入到VelocityTracker当中。
     *
     * @param event
     */
    protected void createVelocityTracker(MotionEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }

    /**
     * 回收VelocityTracker对象。
     */
    protected void recycleVelocityTracker() {
        mVelocityTracker.recycle();
        mVelocityTracker = null;
    }

    /**
     * 获取手指在content界面滑动的速度。
     *
     * @return 滑动速度，以每秒钟移动了多少像素值为单位。
     */
    protected int getFlingXVelocity() {
        mVelocityTracker.computeCurrentVelocity(1000);
        int velocity = (int) mVelocityTracker.getXVelocity();
        return Math.abs(velocity);
    }
    /**
     * 获取手指在content界面滑动的速度。
     *
     * @return 滑动速度，以每秒钟移动了多少像素值为单位。
     */
    protected int getFlingYVelocity() {
        mVelocityTracker.computeCurrentVelocity(1000);
        int velocity = (int) mVelocityTracker.getYVelocity();
        return Math.abs(velocity);
    }

    //=====================get set========================
    public int getUpMinFlingSpeed() {
        return upMinFlingSpeed;
    }

    public void setUpMinFlingSpeed(int upMinFlingSpeed) {
        this.upMinFlingSpeed = convertToDP(upMinFlingSpeed);
    }

    public int getDownMinFlingSpeed() {
        return downMinFlingSpeed;
    }

    public void setDownMinFlingSpeed(int downMinFlingSpeed) {
        this.downMinFlingSpeed = convertToDP(downMinFlingSpeed);
    }

    public int getLeftMinFlingSpeed() {
        return leftMinFlingSpeed;
    }

    public void setLeftMinFlingSpeed(int leftMinFlingSpeed) {
        this.leftMinFlingSpeed = convertToDP(leftMinFlingSpeed);
    }

    public int getRightMinFlingSpeed() {
        return rightMinFlingSpeed;
    }

    public void setRightMinFlingSpeed(int rightMinFlingSpeed) {
        this.rightMinFlingSpeed = convertToDP(rightMinFlingSpeed);
    }

    public int getXTriggerRange() {
        return xTriggerRange;
    }

    public void setXTriggerRange(int xTriggerRange) {
        this.xTriggerRange = convertToDP(xTriggerRange);
    }

    public int getYTriggerRange() {
        return yTriggerRange;
    }

    public void setYTriggerRange(int yTriggerRange) {
        this.yTriggerRange = convertToDP(yTriggerRange);
    }

    public OnFlingUpListener getOnFlingUpListener() {
        return onFlingUpListener;
    }

    public void setOnFlingUpListener(OnFlingUpListener onFlingUpListener) {
        this.onFlingUpListener = onFlingUpListener;
    }

    public OnFlingDownListener getOnFlingDownListener() {
        return onFlingDownListener;
    }

    public void setOnFlingDownListener(OnFlingDownListener onFlingDownListener) {
        this.onFlingDownListener = onFlingDownListener;
    }

    public OnFlingLeftListener getOnFlingLeftListener() {
        return onFlingLeftListener;
    }

    public void setOnFlingLeftListener(OnFlingLeftListener onFlingLeftListener) {
        this.onFlingLeftListener = onFlingLeftListener;
    }

    public OnFlingRightListener getOnFlingRightListener() {
        return onFlingRightListener;
    }

    public void setOnFlingRightListener(OnFlingRightListener onFlingRightListener) {
        this.onFlingRightListener = onFlingRightListener;
    }

    public OnTouchDelegate getOnTouchDelegate() {
        return onTouchDelegate;
    }

    public void setOnTouchDelegate(OnTouchDelegate onTouchDelegate) {
        this.onTouchDelegate = onTouchDelegate;
    }

    public boolean isConsumeTouchEvent() {
        return isConsumeTouchEvent;
    }

    public void setConsumeTouchEvent(boolean consumeTouchEvent) {
        isConsumeTouchEvent = consumeTouchEvent;
    }

    //=====================interface========================
    public interface OnFlingUpListener{
        public void onFlingUp(View v, MotionEvent event);
    }
    public interface OnFlingDownListener{
        public void onFlingDown(View v, MotionEvent event);
    }
    public interface OnFlingLeftListener{
        public void onFlingLeft(View v, MotionEvent event);
    }
    public interface OnFlingRightListener{
        public void onFlingRight(View v, MotionEvent event);
    }
    public interface OnTouchDelegate{
        public boolean onTouch(View v, MotionEvent event);
    }


}
